module ucpoints !points on the unit circle
   use precision
   private
   public ucpoint, as_ucpoint
   public operator(+), operator(-), assignment(=)
   public x, y, theta

   type ucpoint
      private
      real(adequate):: theta = 0.0
   end type ucpoint

   interface assignment(=)
      module procedure ucpoint_set
   end interface

   interface operator(+)
      module procedure ucpoint_add_s, ucpoint_s_add
   end interface

   interface operator(-)
      module procedure ucpoint_subtract_s, &
	     ucpoint_s_subtract, ucpoint_negate
   end interface

contains
   function as_ucpoint(r) result(p)
   real(adequate), intent(in):: r
   type(ucpoint) p
   p = r
   end function as_ucpoint

   function x(p)
   type(ucpoint), intent(in):: p
   real(adequate) x
   x = cos(p%theta)
   end function x

   function y(p)
   type(ucpoint), intent(in):: p
   real(adequate) y
   y = sin(p%theta)
   end function y

   function theta(p)
   type(ucpoint), intent(in):: p
   real(adequate) r
   theta = p%theta
   end function theta

   subroutine ucpoint_set (p, r)
   type(ucpoint), intent(out):: p
   real(adequate), intent(in):: r
   p%theta = modulo(r, 2.0_adequate * pi)
   end subroutine ucpoint_set   


   function ucpoint_add_s (a, b) result(r)
   type(ucpoint), intent(in):: a
   real(adequate), intent(in):: b
   type(ucpoint):: r

   r = a%theta + b
   end function ucpoint_add_s 

   function ucpoint_s_add (a, b) result(r)
   type(ucpoint), intent(in):: b
   real(adequate), intent(in):: a
   type(ucpoint):: r

   r = a + b%theta
   end function ucpoint_s_add

   function ucpoint_negate (a) result(r)
   type(ucpoint), intent(in):: a
   type(ucpoint):: r

   r = -a%theta
   end function ucpoint_negate

   function ucpoint_subtract_s (a, b) result(r)
   type(ucpoint), intent(in):: a
   real(adequate), intent(in):: b
   type(ucpoint):: r

   r = a%theta - b
   end function ucpoint_subtract_s

   function ucpoint_s_subtract (a, b) result(r)
   type(ucpoint), intent(in):: b
   real(adequate), intent(in):: a
   type(ucpoint):: r

   r = a - b%theta
   end function ucpoint_s_subtract

end module ucpoints